import { ref, watch, type Ref } from 'vue'

/**
 * 防抖Hook - 延迟执行函数直到停止调用一段时间后
 */
export function useDebounce<T>(
  value: Ref<T>,
  delay: number = 300
): [Ref<T>, (newValue: T) => void] {
  const debouncedValue = ref(value.value) as Ref<T>
  let timeoutId: NodeJS.Timeout | null = null
  
  const updateDebouncedValue = (newValue: T) => {
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    
    timeoutId = setTimeout(() => {
      debouncedValue.value = newValue
    }, delay)
  }
  
  // 监听原始值变化
  watch(value, (newValue) => {
    updateDebouncedValue(newValue)
  }, { immediate: true })
  
  return [debouncedValue, updateDebouncedValue]
}

/**
 * 防抖函数Hook
 */
export function useDebouncedFunction<T extends (...args: any[]) => any>(
  fn: T,
  delay: number = 300
): T {
  let timeoutId: NodeJS.Timeout | null = null
  
  return ((...args: Parameters<T>) => {
    if (timeoutId) {
      clearTimeout(timeoutId)
    }
    
    timeoutId = setTimeout(() => {
      fn(...args)
    }, delay)
  }) as T
}

/**
 * 节流Hook - 限制函数执行频率
 */
export function useThrottle<T extends (...args: any[]) => any>(
  fn: T,
  delay: number = 300
): [T, () => void] {
  let lastExecTime = 0
  let timeoutId: NodeJS.Timeout | null = null
  
  const throttledFn = ((...args: Parameters<T>) => {
    const now = Date.now()
    
    if (now - lastExecTime >= delay) {
      lastExecTime = now
      fn(...args)
    } else {
      if (timeoutId) {
        clearTimeout(timeoutId)
      }
      
      timeoutId = setTimeout(() => {
        lastExecTime = Date.now()
        fn(...args)
      }, delay - (now - lastExecTime))
    }
  }) as T
  
  const cancel = () => {
    if (timeoutId) {
      clearTimeout(timeoutId)
      timeoutId = null
    }
  }
  
  return [throttledFn, cancel]
}